﻿/*
 * Created by SharpDevelop.
 * User: 김효순
 * Date: 2012-08-27
 * Time: 오전 11:58
 * 
 * To change this template use Tools | Options | Coding | Edit Standard Headers.
 */
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace 마우스
{
	/// <summary>
	/// Description of MainForm.
	/// </summary>
	public partial class MainForm : Form
	{
		[DllImport("User32.dll")]
		public static extern int SetCursorPos(int x, int y);
		
		[DllImport("User32.dll")]
		public static extern bool GetCursorPos(ref Point lpPoint);
		
		[DllImport("User32.dll")]
		public static extern short GetAsyncKeyState(int vKey);
		
		[DllImport("User32.dll")]
		public static extern void mouse_event(long dwFlags, long dx, long dy, long cButtons, long dwExtraInfo);
		
		[DllImport("User32.dll")]
		public static extern int ShowCursor(bool bShow);
		
		[DllImport("User32.dll")]
		public static extern void ClipCursor(ref Rectangle lpRect);
		
		[DllImport("user32.dll")]  
		public static extern void ClipCursor(IntPtr rect);
		
		[DllImport("user32.dll")]
		public static extern void SetDoubleClickTime(long wCount);
		
		[DllImport("user32.dll")]
		public static extern int GetDoubleClickTime();
		
		[DllImport("user32.dll")]  
        private static extern int CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hWnd, int Msg, int wParam, int lParam);
        
        [DllImport("user32.dll")]
        private static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, HookWndProc NewWndProc);
        
        [DllImport("user32.dll")]
        private static extern IntPtr SetWindowLong(IntPtr hWnd, int nIndex, IntPtr OldWndProc);
        
        [DllImport("user32.dll", SetLastError=true)]
        private static extern IntPtr SetWindowsHookEx(int idHook, HookExWndProc NewWndProc, IntPtr hInstance, int dwThreadId);
        	
        [DllImport("user32.dll")]
        private static extern void UnhookWindowsHookEx(IntPtr hHook);
        
        [DllImport("user32.dll")]
        private static extern int CallNextHookEx(IntPtr hHook, int nCode, int wParam, int lParam);



        
        private delegate int HookWndProc(IntPtr hWnd, int Msg, int wParam, int lParam);
        private HookWndProc NewWndProc = null;
        
        private delegate int HookExWndProc(int nCode, int wParam, int lParam);
        private HookExWndProc NewWndProcEx = null;
		
		private Point pt;
		private Rectangle rect;
		IntPtr lPrevWndProc = IntPtr.Zero;
		IntPtr lOldWndProc = IntPtr.Zero;
		
		private const int VK_LBUTTON = 0x1;
		private const int VK_RBUTTON = 0x2;
		private const int VK_MBUTTON = 0x4;             //  NOT contiguous with L RBUTTON
		
		private const int MOUSEEVENTF_LEFTUP = 0x4; //  left button up
		private const int MOUSEEVENTF_LEFTDOWN = 0x2; //  left button down
		private const int MOUSEEVENTF_RIGHTDOWN = 0x8; //  right button down
		private const int MOUSEEVENTF_RIGHTUP = 0x10; //  right button up
		private const int MOUSEEVENTF_MIDDLEDOWN = 0x20; //  middle button down
		private const int MOUSEEVENTF_MIDDLEUP = 0x40; //  middle button up
		
		private const int GWL_WNDPROC = (-4);
		private const int WM_MOUSEWHEEL = 0x20A;
		
		private const int WH_MOUSE = 7;


		
		public MainForm()
		{
			//
			// The InitializeComponent() call is required for Windows Forms designer support.
			//
			InitializeComponent();
			
			//
			// TODO: Add constructor code after the InitializeComponent() call.
			//
		}
		
		void Bt1Click(object sender, EventArgs e)
		{
			SetCursorPos(int.Parse(tb1.Text), int.Parse(tb2.Text));
		}
		
		void Timer1Tick(object sender, EventArgs e)
		{
			GetCursorPos(ref pt);
			
			string st;
			st = string.Format("마우스 위치: {0:d}, {1:d}", pt.X, pt.Y);
			label3.Text = st;
			
			string st1 = "";
			if(Convert.ToBoolean(GetAsyncKeyState(VK_LBUTTON))){
				if(!st1.Equals("")) st1 += ",";
				st1 += "왼쪽";
			}
			
			if(Convert.ToBoolean(GetAsyncKeyState(VK_RBUTTON))){
				if(!st1.Equals("")) st1 += ",";
				st1 += "오른쪽";
			}
			
			if(Convert.ToBoolean(GetAsyncKeyState(VK_MBUTTON))){
				if(!st1.Equals("")) st1 += ",";
				st1 += "중간";
			}
			
			label4.Text = "마우스 상태: " + st1;
		}
		
		void Bt2Click(object sender, EventArgs e)
		{
			int iMouseState = MOUSEEVENTF_LEFTUP;
			
			if(cb1.Checked) iMouseState = MOUSEEVENTF_LEFTDOWN;
			if(cb2.Checked) iMouseState = iMouseState | MOUSEEVENTF_MIDDLEDOWN;
			else iMouseState = iMouseState | MOUSEEVENTF_MIDDLEUP;
			if(cb3.Checked) iMouseState = iMouseState | MOUSEEVENTF_RIGHTDOWN;
			else iMouseState = iMouseState | MOUSEEVENTF_RIGHTUP;
			
			mouse_event(iMouseState, 0, 0, 0, 0);
		}
		
		void Bt3Click(object sender, EventArgs e)
		{
			string bt = "";
			if(bt3.Text == "마우스숨김"){
				bt = "마우스보임";
				ShowCursor(false);
			}else if(bt3.Text == "마우스보임"){
				bt = "마우스숨김";
				ShowCursor(true);
			}
			bt3.Text = bt;
		}
		
		void Bt4Click(object sender, EventArgs e)
		{
			if(bt4.Text == "마우스위치제한"){
				bt4.Text = "마우스위치제한해제";
				
				rect = new Rectangle(this.Left, this.Top, this.Right, this.Bottom );
				ClipCursor(ref rect);
			}else if(bt4.Text == "마우스위치제한해제"){
				bt4.Text = "마우스위치제한";
				
				ClipCursor(IntPtr.Zero);
			}
		}
		
		void pn1DoubleClick(object sender, EventArgs e)
		{
			if(pn1.BackColor.Equals(Color.Black)){
				pn1.BackColor = Color.Red;
			} else if(pn1.BackColor.Equals(Color.Red)){
				pn1.BackColor = Color.Black;
			}
		}
		
		void bt5Click(object sender, EventArgs e)
		{
			int t = int.Parse(tb3.Text);
			
			SetDoubleClickTime(t);
			
			tb3.Text = GetDoubleClickTime().ToString();
		}
		
		void Bt6Click(object sender, EventArgs e)
		{
			if(bt6.Text.Equals("setWindowLong")){
				bt6.Text = "setWindowLong해제";
				
				NewWndProc = new HookWndProc(MouseHook1);
				lPrevWndProc = SetWindowLong(this.Handle, GWL_WNDPROC, NewWndProc);
			}else if(bt6.Text.Equals("setWindowLong해제")){
				bt6.Text = "setWindowLong";
				
				SetWindowLong(this.Handle, GWL_WNDPROC, lPrevWndProc);
			}
		}
		
		private int MouseHook1(IntPtr hWnd, int Msg, int wParam, int lParam)
		{
			int fwKeys, zDelta, xPos, yPos;
			string myMsg = "";
			
			if(Msg.Equals(WM_MOUSEWHEEL)){
				fwKeys = wParam & 65535;
				zDelta = wParam / 65536;
				xPos = lParam & 65535;
				yPos = lParam / 65536;
				
				if(!fwKeys.Equals(0)) myMsg = "휠눌림";
				if(zDelta > 0){
					if(!myMsg.Equals("")) myMsg += ",";
					myMsg += "위로" + zDelta.ToString() + "휠";
				}else if(zDelta < 0){
					if(!myMsg.Equals("")) myMsg += ",";
					myMsg += "아래로" + (zDelta*-1).ToString() + "휠";
				}
				
				if(!myMsg.Equals("")) myMsg += ",";
				myMsg += "위치: " + xPos.ToString() + ", " + yPos.ToString();
				
				label5.Text = myMsg;
			}
			
			return CallWindowProc(lPrevWndProc, hWnd, Msg, wParam, lParam);
		}
		
		void Bt7Click(object sender, EventArgs e)
		{
			if(bt7.Text.Equals("setWindowHookEx")){
				bt7.Text = "setWindowHookEx해제";
				
				NewWndProcEx = new HookExWndProc(MouseHook2);
				
				lOldWndProc = SetWindowsHookEx(WH_MOUSE, NewWndProcEx, (IntPtr)0, AppDomain.GetCurrentThreadId());
			} else if(bt7.Text.Equals("setWindowHookEx해제")){
				bt7.Text = "setWindowHookEx";
				
				UnhookWindowsHookEx(lOldWndProc);
			}
		}
		
		private int MouseHook2(int nCode, int wParam, int lParam)
		{
			if(nCode < 0){
				return CallNextHookEx(lOldWndProc, nCode, wParam, lParam);
			}
			
			string st = string.Format("nCode={0:d}, wParam={1:n}, lParam={2:x}", nCode, wParam, lParam);
			label5.Text = st;
			
			return CallNextHookEx(lOldWndProc, nCode, wParam, lParam);
		}
	}
}
